#include<iostream>
#include<cstdio>
#include<unistd.h>
#include<signal.h>

using namespace std;

volatile int g_val;
//int g_val;

void handler(int signo)
{
    (void)signo; //骗过编译器,不要警告,此变量不光光是定义,在后面还使用了它
    g_val = 1; 
    //g_val = 1;  //对存放在内存中的g_val值进行修改,不会自动更新寄存器的值
    cout << "g_val由0变为1" << endl;
}

int main()
{
    signal(2, handler);
    /*编译器会作优化,将存放在内存中的g_val值拷贝到CPU寄存器中,
    之后直接从寄存器中读取此变量的值*/
    while(!g_val) ; 
    printf("process normal quit!\n");
    
    return 0;
}

// void handle(int signo) //未终止进程,导致异常一直存在
// {
//     cout << "get signumber: " << signo << endl; 
//     sleep(1); 
// }

// int main()
// {
//     signal(SIGSEGV, handle);

//     int* p = NULL; //非法访问野指针,会导致野指针异常
//     *p = 10;

//     // int a = 0, b = 3;
//     // int c = b / a; //除数为0,会导致除零错误

//     while(true)
//         sleep(1);

//     return 0;
// }

// int cnt;

// /*如果在信号处理函数中设置了alarm(2),并且接着是一个死循环,
// 现象:在2秒过后OS尝试发送SIGALRM信号,由于进入了死循环,
// 意味着处理函数不会返回,导致新的信号无法被处理,因为无法进入该信号处理函数*/
// void handle(int signo) 
// {
//     cout << "catching..." << endl;
//    int n = alarm(2); //在上一个定时器调用前,设置一个全新的定时器
//    cout << "alarm(2) retval" << n << endl; //离之前设置的定时器剩余的时间
// }

// int main()
// {
//     signal(SIGALRM, handle); //设置SIGALRM信号的捕捉方法
//     alarm(10); //设置一个定时器
    
//     while(true)
//     {
//         cout << "I am a process, pid: " << getpid() << endl;
//         sleep(1);
//     }

//     return 0;
// }

// int main()
// {
//     signal(14, handle); //对SIGALAM信号进行捕捉

//     alarm(50); 
    
//     int cnt = 5;
//     while(cnt--)
//     {
//         cout << "I am a process, pid: " << getpid() << endl;
//         sleep(1);
//         if(cnt == 3)  
//         {
//             size_t n = alarm(0); //取消之前设定的定时器
//             cout << "alarm(0) retval " << n << endl; //返回值为离之前设置的定时器剩余的时间
//         }
//     }

//     return 0;
// }

// int main()
// {
//     signal(6, handle); //设定信号捕捉的方法

//     int cnt = 4;
//     while(cnt--)
//     {
//         cout << "I am a process, pid: " << getpid() << endl;
//         if(cnt == 2) abort(); //给当前进程发送指定信号(6号信号)
//         sleep(1);
//     }

//     return 0;
// }